<?php
/**
 * Created by PhpStorm.
 * User: Ysll <754060604@qq.com>
 * Date: 2017/9/29
 * Time: 15:03
 */

namespace Common\Common;

use Think\Verify;

class Validator
{
    /**
     * 错误
     *
     * @var array
     */
    protected $error = array();

    /**
     * 需要验证的数据
     *
     * @var array
     */
    protected $data = array();

    /**
     * 验证规则
     *
     * @var array
     */
    protected $rule = array();

    /**
     * 验证是否失败
     *
     * @var bool
     */
    protected $failed = false;

    /**
     * ValidatorForm constructor.
     * @param array $data
     * @param array $rule
     */
    public function __construct(array $data, array $rule)
    {
        $this->data = $data;
        $this->rule = $rule;
        $this->validator();
    }

    /**
     * @param array $data
     * @param array $rule
     * @return static|Validator
     */
    public static function make(array $data, array $rule)
    {
        return new static($data, $rule);
    }

    /**
     * @return bool
     */
    public function filed()
    {
        return $this->failed;
    }

    private function validator()
    {
        foreach ($this->rule as $key => $rules) {
            if (is_string($rules)) {
                $rules = explode('|', $rules);
            }
            foreach ($rules as $rule) {
                $params = explode(':', $rule, 2);
                $method = $params[0];
                if (sizeof($params) == 2) {
                    $this->$method($key, $params[1]);
                } else {
                    $this->$method($key);
                }
            }
        }
    }

    public function __call($name, $arguments)
    {
    }

    /**
     * 必须
     *
     * @param $key
     */
    private function required($key)
    {
        if (!$this->isSets($key)) {
            $this->addErrorMessage($key, "$key 是必须的");
        }
    }

    /**
     * 判断是否是email
     *
     * @param $key
     */
    private function email($key)
    {
        if ($this->isSets($key)) {
            $reg = '/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/';
            if (preg_match($reg, $this->data[$key]) === 0) {
                $this->addErrorMessage($key, '必须是邮箱格式');
            }
        }
    }

    /**
     * 最大长度
     *
     * @param $key
     * @param $length
     */
    private function max($key, $length)
    {
        if ($this->isSets($key)) {
            if (mb_strlen($this->data[$key]) > $length) {
                $this->addErrorMessage($key, '长度必须小于' . $length);
            }
        }
    }

    /**
     * 最小长度
     *
     * @param $key
     * @param $length
     */
    private function min($key, $length)
    {
        if ($this->isSets($key)) {
            if (mb_strlen($this->data[$key]) < $length) {
                $this->addErrorMessage($key, '长度必须大于' . $length);
            }
        }
    }

    /**
     * 是否是数字
     *
     * @param $key
     */
    private function integer($key)
    {
        if ($this->isSets($key)) {
            $reg = '/\d{1,}/';
            if (preg_match($reg, $this->data[$key]) === 0) {
                $this->addErrorMessage($key, '必须是数字');
            }
        }
    }

    /**
     * 是否是boolean
     *
     * @param $key
     */
    private function boolean($key)
    {
        if ($this->isSets($key)) {
            $bool = ['true', 'false', '0', '1', 'on', 'off'];
            if (!in_array($this->data[$key], $bool)) {
                $this->addErrorMessage($key, '必须是bool');
            }
        }

    }

    /**
     * 是否是唯一
     *
     * @param $key
     * @param $params
     */
    private function unique($key, $params)
    {
        if ($this->isSets($key)) {
            $params = explode(',', $params, 3);
            $model = M($params[0]);
            $user = $model->where($params[1] . ' = "' . $this->data[$key] . '"')->find();
            $defaultID = isset($params[2]) ? intval($params[2]) : 0;
            if (!empty($user) && $defaultID != $user['id']) {
                $this->addErrorMessage($key, '已存在');
            }
        }
    }


    /**
     * 是否存在
     *
     * @param $key
     * @param $params
     */
    private function exists($key, $params)
    {
        if ($this->isSets($key)) {
            $params = explode(',', $params, 2);
            $model = M($params[0]);
            $user = $model->where($params[1] . ' = "' . $this->data[$key] . '"')->find();
            if (empty($user)) {
                $this->addErrorMessage($key, '不存在');
            }
        }
    }

    /**
     * 验证字段值是否一样
     *
     * @param $key
     * @param null $defaultKey
     */
    private function confirmed($key, $defaultKey = null)
    {
        if ($defaultKey === null) {
            $defaultKey = $key . '_' . 'confirmation';
        }
        if ($this->isSets($key) && $this->isSets($defaultKey)) {
            if ($this->data[$key] !== $this->data[$defaultKey]) {
                $this->addErrorMessage($defaultKey, '两次输入不一致');
            }
        } else {
            $this->addErrorMessage($defaultKey, '两次输入不一样');
        }
    }

    /**
     * 验证验证码 code:value
     *
     * @param string $key
     * @param string $value
     */
    private function code($key, $value = '')
    {
        $code = $this->data[$key];
        $verify = new Verify();
        if (!$verify->check($code, $value)) {
            $this->addErrorMessage($key, '验证码不正确');
        }
    }

    private function between($key, $params)
    {
        if ($this->isSets($key)) {
            $params = explode(',', $params, 2);
            $min = intval($params[0]);
            $max = intval($params[1]);
            $size = intval($this->data[$key]);

            if ($size < $size || $size > $max) {
                $this->addErrorMessage($key, "必须在 $min - $max 之间");
            }
        }
    }

    private function file($key, $type = null)
    {
        if (!$this->isSetFile($key)) {
            return;
        }
        if ($type == null) {
            return;
        }
        $file = $_FILES[$key];
        if (strpos($file['type'], $type) === false) {
            $this->addErrorMessage($key, '类型不一样');
        }
    }

    private function is_array($key)
    {
        if ($this->isSets($key)) {
            if (!is_array($this->data[$key])) {
                $this->addErrorMessage($key, '不是数组');
            }
        }
    }

    public function error()
    {
        return $this->error;
    }

    /**
     * @param $key
     * @param $message
     */
    private function addErrorMessage($key, $message)
    {
        $this->failed = true;
        $this->error[$key][] = $message;
    }

    /**
     * @param $key
     * @return bool
     */
    private function isSets($key)
    {
        return (isset($this->data[$key]) && $this->data[$key] != '');
    }

    private function isSetFile($key)
    {
        return isset($_FILES[$key]) && $_FILES[$key]['error'] == 0;
    }
}
